/*************************************************************
 * File: JsonExtensionProvider.java
 * Copyright (c) 2012
 * Author: Shaobin.Software@gmail.com Shaobin_Software@163.com 
 * Date: Sep 24, 2012
 * Description: 
 ************************************************************/

package snow.core.web.restlet;

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.nio.charset.Charset;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.Provider;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.restlet.Request;
import org.restlet.ext.jaxrs.internal.provider.JsonProvider;
import org.restlet.ext.servlet.ServletUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.MessageSource;
import org.springframework.util.Assert;

import snow.core.toolkit.format.JsonDataFormatter;

/**
 * 扩展的JsonProvider
 * 
 * @author Shaobin.Software@gmail.com Shaobin_Software@163.com
 * @version 1.0
 */
@Provider
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class JsonExtensionProvider extends JsonProvider implements InitializingBean {

	private final Log log = LogFactory.getLog(getClass());

	private JsonDataFormatter jsonDataFormatter;
	private MessageSource messageSource;

	public void afterPropertiesSet() throws Exception {
		Assert.notNull(jsonDataFormatter, "The property [jsonDataFormatter] must not be null!");
	}

	/**
	 * 获取当前字符集
	 * 
	 * @return
	 */
	private Charset getCurrentCharset() {
		Charset charset = Charset.defaultCharset();
		HttpServletRequest request = ServletUtils.getRequest(Request.getCurrent());
		try {
			charset = Charset.forName(request.getCharacterEncoding());
		} catch (Exception e) {
			log.warn(e.getMessage(), e);
		}
		return charset;
	}

	public JsonDataFormatter getJsonDataFormatter() {
		return this.jsonDataFormatter;
	}

	public MessageSource getMessageSource() {
		return this.messageSource;
	}

	public void setJsonDataFormatter(JsonDataFormatter jsonDataFormatter) {
		this.jsonDataFormatter = jsonDataFormatter;
	}

	public void setMessageSource(MessageSource messageSource) {
		this.messageSource = messageSource;
	}

	/**
	 * 输出Json串
	 * 
	 * @param object
	 * @param type
	 * @param genericType
	 * @param annotations
	 * @param mediaType
	 * @param httpHeaders
	 * @param entityStream
	 * @throws IOException
	 * @see org.restlet.ext.jaxrs.internal.provider.JsonProvider#writeTo(java.lang.Object, java.lang.Class, java.lang.reflect.Type,
	 *      java.lang.annotation.Annotation[], javax.ws.rs.core.MediaType, javax.ws.rs.core.MultivaluedMap, java.io.OutputStream)
	 */
	public void writeTo(Object object, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType,
			MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException {
		final OutputStreamWriter writer = new OutputStreamWriter(entityStream, getCurrentCharset());
		writer.write(jsonDataFormatter.format(object));
		writer.flush();
	}
}
